package com.bkbw.live.common.notifycenter;

import static org.junit.Assert.*;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class GameNotificationCenterTest {
	
	static class Param 
	{
		int a;
		int b;
		Param(int i, int j) 
		{
			a = i;
			b = j;
		}
	}
	
	static class SumHandler implements GameNotifyHandler 
	{
		@Override
		public void handle(Object sender, Object param) {
			//System.out.println("s sender is " + sender);
			if (param instanceof Param) {
				Param pa = (Param) param;
				System.out.println("s sum is " + (pa.a + pa.b));
			}
		}
	}
	
	static class MulHandler implements GameNotifyHandler 
	{
		@Override
		public void handle(Object sender, Object param) {
			//System.out.println("m sender is " + sender);
			if (param instanceof Param) {
				Param pa = (Param) param;
				System.out.println("m mul is " + (pa.a * pa.b));
			}
		}
	}
	
	SumHandler shandler = new SumHandler();
	MulHandler mhandler = new MulHandler();
	MulHandler mhandler2 = new MulHandler();
	MulHandler mhandler3 = new MulHandler();

	@Before
	public void setUp() throws Exception {
		
		
	}

	@After
	public void tearDown() throws Exception {
	}

	@Test
	public void testPostNotification() {
		GameNotificationCenter nc = GameNotificationCenter.getInstance();
		System.out.println("normal");
		nc.registerEventHandler(GameNotifyEvent.TestOne, shandler);
		nc.registerEventHandler(GameNotifyEvent.TestOne, mhandler);
		nc.registerEventHandler(GameNotifyEvent.TestTwo, shandler);
		nc.registerEventHandler(GameNotifyEvent.TestTwo, mhandler);
		nc.postNotification(GameNotifyEvent.TestOne, shandler, new Param(1, 1)); // shandler & mhandler will take action
		nc.removeEventHandler(GameNotifyEvent.TestOne, mhandler);
		nc.postNotification(GameNotifyEvent.TestOne, shandler, new Param(3, 3)); // only shandler will take action
		nc.postNotification(GameNotifyEvent.TestTwo, shandler, new Param(5, 5)); // shandler & mhandler will take action
		
		System.out.println("closure as handler");
		GameNotifyHandler lhandler = mhandler2::handle; // mhandler3::handle作为闭包传递
		nc.registerEventHandler(GameNotifyEvent.TestThree, lhandler);
		nc.postNotification(GameNotifyEvent.TestThree, mhandler2, new Param(6, 6)); // mhandler2 will take action
		nc.removeEventHandler(GameNotifyEvent.TestThree, lhandler);
		nc.postNotification(GameNotifyEvent.TestThree, mhandler2, new Param(6, 6)); // mhandler2 will not take action
		
		System.out.println("lambda");
		GameNotifyHandler lambda = (Object sender, Object param) -> {
			mhandler2.handle(sender, param);
			
		};
		nc.registerEventHandler(GameNotifyEvent.TestThree, lambda);
		nc.postNotification(GameNotifyEvent.TestThree, mhandler2, new Param(6, 6));
		
		
		System.out.println("closure is a anonymous class, can't be a delegate as csharp");
		// 可以把闭包作为handler传递给nc，但是，事实上java的闭包是被一个叫lambda的匿名类包含，所以无法得到相同对象
		// mhandler3::handle连续调用两次，会生成两个不同的对象，和csharp的委托完全不同，csharp的委托能够得到同一个对象
		nc.registerEventHandler(GameNotifyEvent.TestThree, mhandler3::handle);
		nc.postNotification(GameNotifyEvent.TestThree, shandler, new Param(7, 7));// will action
		nc.removeEventHandler(GameNotifyEvent.TestThree, mhandler3::handle);//又生成了一个新闭包，第一个mhandler2::handle没有被移除
		nc.postNotification(GameNotifyEvent.TestThree, shandler, new Param(8, 8));// not moved, so will take action

	}


}
